home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PROGRAMM
/
CC_C
/
1199.ZIP
/
CLIB.ARC
< prev
next >
Wrap
Text File
|
1988-06-15
|
53KB
|
2,077 lines
>>> CLIB.H 1617
/*
** CLIB.H -- Definitions for Small-C library functions.
**
** Copyright 1983 L. E. Payne and J. E. Hendrix
*/
/*
** Misc parameters
*/
#define MAXFILES 20 /* maximum open files */
#define DOSEOF 26 /* DOS end-of-file byte */
#define ARCHIVE 32 /* file archive bit */
/*
** DOS function calls
*/
#define CREATE 60 /* make file */
#define OPEN 61 /* open file */
#define CLOSE 62 /* close file or device */
#define READ 63 /* read from a file */
#define WRITE 64 /* write to a file */
#define DELETE 65 /* delete file */
#define SEEK 66 /* seek within a file */
#define CONTROL 68 /* control device */
#define FORCE 70 /* force use of a handle */
#define RETDOS 76 /* close files and return to DOS */
#define FNDFIL 78 /* find first occurrence of a file */
#define FNDNXT 79 /* find next occurrence of a file */
#define RENAME 86 /* rename file */
/*
** File status bits
*/
#define OPNBIT 1 /* open condition */
#define EOFBIT 2 /* end-of-file condition */
#define ERRBIT 4 /* error condition */
/*
** File positioning origins
*/
#define FROM_BEG 0 /* from beginning of file */
#define FROM_CUR 1 /* from current position */
#define FROM_END 2 /* from end of file */
/*
** Buffer usage codes
** NULL means the buffer is not used.
*/
#define EMPTY 1 /* buffer is currently empty */
#define IN 2 /* buffer is currently holding input data */
#define OUT 3 /* buffer is currently holding output data */
/*
** ASCII characters
*/
#define ABORT 3
#define RUB 8
#define PAUSE 19
#define WIPE 24
#define DEL 127
>>> ABS.C 117
/*
** abs -- returns absolute value of nbr
*/
abs(nbr) int nbr; {
if(nbr < 0) return (-nbr);
return (nbr);
}
>>> ATOI.C 259
/*
** atoi(s) - convert s to integer.
*/
atoi(s) char *s; {
int sign, n;
while(isspace(*s)) ++s;
sign = 1;
switch(*s) {
case '-': sign = -1;
case '+': ++s;
}
n = 0;
while(isdigit(*s)) n = 10 * n + *s++ - '0';
return (sign * n);
}
>>> ATOIB.C 435
/*
** atoib(s,b) - Convert s to "unsigned" integer in base b.
** NOTE: This is a non-standard function.
*/
atoib(s, b) char *s; int b; {
int n, digit;
n = 0;
while(isspace(*s)) ++s;
while((digit = (127 & *s++)) >= '0') {
if(digit >= 'a') digit -= 87;
else if(digit >= 'A') digit -= 55;
else digit -= '0';
if(digit >= b) break;
n = b * n + digit;
}
return (n);
}
>>> AUXBUF.C 786
#include "stdio.h"
#include "clib.h"
extern int
_bufsiz[MAXFILES], /* size of buffer */
_bufptr[MAXFILES]; /* aux buffer address */
/*
** auxbuf -- allocate an auxiliary input buffer for fd
** fd = file descriptor of an open file
** size = size of buffer to be allocated
** Returns NULL on success, else ERR.
** Note: Ungetc() still works.
** A 2nd call allocates a new buffer replacing old one.
** If fd is a device, buffer is allocated but ignored.
** Buffer stays allocated when fd is closed or new one is allocated.
** May be used on a closed fd.
*/
auxbuf(fd, size) int fd; char *size; { /* fake unsigned */
if(!size || avail(NO) < size) return (ERR);
_bufptr[fd] = malloc(size);
_bufsiz[fd] = size;
_empty(fd, NO);
return (NULL);
}
>>> AVAIL.C 347
extern char *_memptr;
/*
** Return the number of bytes of available memory.
** In case of a stack overflow condition, if 'abort'
** is non-zero the program aborts with an 'S' clue,
** otherwise zero is returned.
*/
avail(abort) int abort; {
char x;
if(&x < _memptr) {
if(abort) exit(1);
return (0);
}
return (&x - _memptr);
}
>>> BSEEK.C 727
#include "stdio.h"
#include "clib.h"
extern int _nextc[], _bufuse[];
/*
** Position fd to the character in file indicated by "offset."
** "Offset" is the address of a long integer or array of two
** integers containing the offset, low word first.
**
** BASE OFFSET-RELATIVE-TO
** 0 beginning of file
** 1 current byte in file
** 2 end of file (minus offset)
**
** Returns NULL on success, else EOF.
*/
bseek(fd, offset, base) int fd, offset[], base; {
int hi, lo;
if(!_mode(fd) || !_bufuse[fd]) return (EOF);
if(_adjust(fd)) return (EOF);
lo = offset[0];
hi = offset[1];
if(!_seek(base, fd, &hi, &lo)) return (EOF);
_nextc[fd] = EOF;
_clreof(fd);
return (NULL);
}
>>> BTELL.C 447
#include "stdio.h"
#include "clib.h"
extern int _bufuse[];
/*
** Retrieve offset to next character in fd.
** "Offset" must be the address of a long int or
** a 2-element int array. The offset is placed in
** offset in low, high order.
*/
btell(fd, offset) int fd, offset[]; {
if(!_mode(fd) || !_bufuse[fd]) return (EOF);
if(_adjust(fd)) return (EOF);
offset[0] = offset[1] = 0;
_seek(FROM_CUR, fd, offset+1, offset);
return (NULL);
}
>>> CALL.ASM 3939
;
; Small-C Run Time Library for MS/PC-DOS
;
extrn __main: near
extrn _exit: near
extrn __memptr: word
data segment public
dw 1
data ends
stack segment stack
dw 32 dup(?)
stack ends
code segment public
assume cs:code
start:
mov ax,data ; set data segment for program
mov ds,ax
mov ax,es:[2] ; paragraphs of memory on system
sub ax,data ; paragraphs beyond code segment
cmp ah,10h ; more than 64K?
jb start_1 ; no
mov ax,1000h ; only use 64K
start_1:
mov cl,4
shl ax,cl ; byte offset to end of data/free/stack
cli ; disable interrupts
mov bx,ds
mov ss,bx ; make data and stack segments coincide
mov sp,ax ; top of stack = end of data/free/stack
push ax ; force sp non-zero (if 64K used)
sti ; reenable interrupts
mov ax,stack ; paragraph following data
sub ax,data ; number of data paragraphs
shl ax,cl ; number of data bytes (offset to free/stack)
mov bx,ax
inc bh ; adjust for minimum stack space
cmp bx,sp ; enough memory?
jb start_2 ; yes
mov ax,1 ; no, terminate with exit code 1
push ax
call _exit
start_2:
mov __memptr,ax ; set memory allocation pointer
;
; ------------ release unused memory -----------
; ------ cannot run debug with this code -------
; mov bx,sp
; mov ah,4AH
; int 21H
; ----------------------------------------------
;
; make sure that es -> psp, because __main requires it
;
jmp __main ; __main never returns
public _ccargc
_ccargc:
mov al,cl
xor ah,ah
ret
;
; Test if Secondary (BX) <oper> Primary (AX)
;-------------------------- MASM version
;compare macro name, cond
; public __&name
;__&name:
; cmp ax,bx
; j&cond true
; xor ax,ax ; returns zero
; ret
; endm
;-------------------------- ASM version
compare macro name, cond
public __?1
__?1:
cmp ax,bx
j?2 true
xor ax,ax ; returns zero
ret
endm
;--------------------------
compare ult,a
compare ugt,b
compare ule,ae
compare uge,be
compare eq,e
compare ne,ne
compare lt,g
compare gt,l
compare le,ge
compare ge,le
;
; Logical Negate of Primary
;
public __lneg
__lneg:
or ax,ax
jnz false
true: mov ax,1 ; returns one
ret
false: xor ax,ax ; returns zero
ret
;
;
; execute "switch" statement
;
; ax = switch value
; (sp) -> switch table
; dw addr1, value1
; dw addr2, value2
; ...
; dw 0
; [jmp default]
; continuation
;
public __switch
__switch:
pop bx ; bx -> switch table
jmp skip ; skip the pre-increment
back:
add bx,4
skip: mov cx,cs:[bx]
jcxz default ; end of table -- jump out
cmp ax,cs:[bx+2]
jnz back
jmp cx ; match -- jump to case
default:
inc bx
inc bx
jmp bx ; jump to default/continuation
;
; dummy entry point to resolve the external reference _LINK
; which is no longer generated by Small-C but which exists in
; library modules and .OBJ files compiled by earlier versions
; of Small-C
public __link
__link: ret
code ends
end start
>>> CALLOC.C 315
#include "stdio.h"
/*
** Cleared-memory allocation of n items of size bytes.
** n = Number of items to allocate space for.
** size = Size of the items in bytes.
** Returns the address of the allocated block,
** else NULL for failure.
*/
calloc(n, size) unsigned n, size; {
return (_alloc(n*size, YES));
}
>>> CLEARERR.C 152
#include "stdio.h"
#include "clib.h"
extern int _status[];
/*
** Clear error status for fd.
*/
clearerr(fd) int fd; {
if(_mode(fd)) _clrerr(fd);
}
>>> CSEEK.C 1539
#include "stdio.h"
#include "clib.h"
extern int _nextc[], _bufuse[];
/*
** Position fd to the 128-byte record indicated by
** "offset" relative to the point indicated by "base."
**
** BASE OFFSET-RELATIVE-TO
** 0 first record
** 1 current record
** 2 end of file (last record + 1)
** (offset should be minus)
**
** Returns NULL on success, else EOF.
*/
cseek(fd, offset, base) int fd, offset, base; {
int newrec, oldrec, hi, lo;
if(!_mode(fd) || !_bufuse[fd]) return (EOF);
if(_adjust(fd)) return (EOF);
switch (base) {
case 0: newrec = offset;
break;
case 1: oldrec = ctell(fd);
goto calc;
case 2: hi = lo = 0;
if(!_seek(FROM_END, fd, &hi, &lo)) return (EOF);
oldrec = ((lo >> 7) & 511) | (hi << 9);
calc:
newrec = oldrec + offset;
break;
default: return (EOF);
}
lo = (newrec << 7); /* convert newrec to long int */
hi = (newrec >> 9) & 127;
if(!_seek(FROM_BEG, fd, &hi, &lo)) return (EOF);
_nextc[fd] = EOF;
_clreof(fd);
return (NULL);
}
/*
** Position fd to the character indicated by
** "offset" within current 128-byte record.
** Must be on record boundary.
**
** Returns NULL on success, else EOF.
*/
cseekc(fd, offset) int fd, offset; {
int hi, lo;
if(!_mode(fd) || isatty(fd) ||
ctellc(fd) || offset < 0 || offset > 127) return (EOF);
hi = 0; lo = offset;
if(!_seek(FROM_CUR, fd, &hi, &lo)) return (EOF);
return (NULL);
}
>>> CSYSLIB.C 9708
/*
** CSYSLIB -- System-Level Library Functions
*/
#include "stdio.h"
#include "clib.h"
/*
****************** System Variables ********************
*/
int
_cnt=1, /* arg count for main */
_vec[20], /* arg vectors for main */
_status[MAXFILES] = {OPNBIT, OPNBIT, OPNBIT, OPNBIT, OPNBIT},
_cons [MAXFILES], /* fast way to tell if file is the console */
_nextc [MAXFILES] = {EOF, EOF, EOF, EOF, EOF},
_bufuse[MAXFILES], /* current buffer usage: NULL, EMPTY, IN, OUT */
_bufsiz[MAXFILES], /* size of buffer */
_bufptr[MAXFILES], /* aux buffer address */
_bufnxt[MAXFILES], /* address of next byte in buffer */
_bufend[MAXFILES], /* address of end-of-data in buffer */
_bufeof[MAXFILES]; /* true if current buffer ends file */
char
*_memptr, /* pointer to free memory. */
_arg1[]="*"; /* first arg for main */
/*
*************** System-Level Functions *****************
*/
/*
** Process command line, allocate default buffer to each fd,
** execute main(), and exit to DOS. Must be executed with es=psp.
** Small default buffers are allocated because a high price is paid for
** byte-by-byte calls to DOS. Tests gave these results for a simple
** copy program:
**
** chunk size copy time in seconds
** 1 36
** 5 12
** 25 6
** 50 6
*/
_main() {
int fd;
_parse();
for(fd = 0; fd < MAXFILES; ++fd) auxbuf(fd, 32);
if(!isatty(stdin)) _bufuse[stdin] = EMPTY;
if(!isatty(stdout)) _bufuse[stdout] = EMPTY;
main(_cnt, _vec);
exit(0);
}
/*
** Parse command line and setup argc and argv.
** Must be executed with es == psp
*/
_parse() {
char *ptr;
#asm
mov cl,es:[80h] ; get parameter string length
mov ch,0
push cx ; save it
inc cx
push cx ; 1st __alloc() arg
mov ax,1
push ax ; 2nd __alloc() arg
call __alloc ; allocate zeroed memory for args
add sp,4
mov [bp-2],ax ; ptr = addr of allocated memory
pop cx
push es ; exchange
push ds ; es (source)
pop es ; and
pop ds ; ds (destination)
mov si,81h ; source offset
mov di,[bp-2] ; destination offset
rep movsb ; move string
mov al,0
stosb ; terminate with null byte
push es
pop ds ; restore ds
#endasm
_vec[0]=_arg1; /* first arg = "*" */
while (*ptr) {
if(isspace(*ptr)) {++ptr; continue;}
if(_cnt < 20) _vec[_cnt++] = ptr;
while(*ptr) {
if(isspace(*ptr)) {*ptr = NULL; ++ptr; break;}
++ptr;
}
}
}
/*
** Open file on specified fd.
*/
_open(fn, mode, fd) char *fn, *mode; int *fd; {
int rw, tfd;
switch(mode[0]) {
case 'r': {
if(mode[1] == '+') rw = 2; else rw = 0;
if ((tfd = _bdos2((OPEN<<8)|rw, NULL, NULL, fn)) < 0) return (NO);
break;
}
case 'w': {
if(mode[1] == '+') rw = 2; else rw = 1;
create:
if((tfd = _bdos2((CREATE<<8), NULL, ARCHIVE, fn)) < 0) return (NO);
_bdos2(CLOSE<<8, tfd, NULL, NULL);
if((tfd = _bdos2((OPEN<<8)|rw, NULL, NULL, fn)) < 0) return (NO);
break;
}
case 'a': {
if(mode[1] == '+') rw = 2; else rw = 1;
if((tfd = _bdos2((OPEN<<8)|rw, NULL, NULL, fn)) < 0) goto create;
if(_bdos2((SEEK<<8)|FROM_END, tfd, NULL, 0) < 0) return (NO);
break;
}
default: return (NO);
}
_empty(tfd, YES);
if(isatty(tfd)) _bufuse[tfd] = NULL;
*fd = tfd;
_cons [tfd] = NULL;
_nextc [tfd] = EOF;
_status[tfd] = OPNBIT;
return (YES);
}
/*
** Binary-stream input of one byte from fd.
*/
_read(fd) int fd; {
unsigned char ch;
if(_nextc[fd] != EOF) {
ch = _nextc[fd];
_nextc[fd] = EOF;
return (ch);
}
if(iscons(fd)) return (_getkey());
if(_bufuse[fd]) return(_readbuf(fd));
switch(_bdos2(READ<<8, fd, 1, &ch)) {
case 1: return (ch);
case 0: _seteof(fd); return (EOF);
default: _seterr(fd); return (EOF);
}
}
/*
** Fill buffer if necessary, and return next byte.
*/
_readbuf(fd) int fd; {
int got, chunk;
char *ptr, *max;
if(_bufuse[fd] == OUT && _flush(fd)) return (EOF);
while(YES) {
ptr = _bufnxt[fd];
if(ptr < _bufend[fd]) {++_bufnxt[fd]; return (*ptr);}
if(_bufeof[fd]) {_seteof(fd); return (EOF);}
max = (ptr = _bufend[fd] = _bufptr[fd]) + _bufsiz[fd];
do { /* avoid DMA problem on physical 64K boundary */
if((max - ptr) < 512) chunk = max - ptr;
else chunk = 512;
ptr += (got = _bdos2(READ<<8, fd, chunk, ptr));
if(got < chunk) {_bufeof[fd] = YES; break;}
} while(ptr < max);
_bufend[fd] = ptr;
_bufnxt[fd] = _bufptr[fd];
_bufuse[fd] = IN;
}
}
/*
** Binary-Stream output of one byte to fd.
*/
_write(ch, fd) int ch, fd; {
if(_bufuse[fd]) return(_writebuf(ch, fd));
if(_bdos2(WRITE<<8, fd, 1, &ch) != 1) {
_seterr(fd);
return (EOF);
}
return (ch);
}
/*
** Empty buffer if necessary, and store ch in buffer.
*/
_writebuf(ch, fd) int ch, fd; {
char *ptr;
if(_bufuse[fd] == IN && _backup(fd)) return (EOF);
while(YES) {
ptr = _bufnxt[fd];
if(ptr < (_bufptr[fd] + _bufsiz[fd])) {
*ptr = ch;
++_bufnxt[fd];
_bufuse[fd] = OUT;
return (ch);
}
if(_flush(fd)) return (EOF);
}
}
/*
** Flush buffer to DOS if dirty buffer.
** Reset buffer pointers in any case.
*/
_flush(fd) int fd; {
int i, j, k, chunk;
if(_bufuse[fd] == OUT) {
i = _bufnxt[fd] - _bufptr[fd];
k = 0;
while(i > 0) { /* avoid DMA problem on physical 64K boundary */
if(i < 512) chunk = i;
else chunk = 512;
k += (j = _bdos2(WRITE<<8, fd, chunk, _bufptr[fd] + k));
if(j < chunk) {_seterr(fd); return (EOF);}
i -= j;
}
}
_empty(fd, YES);
return (NULL);
}
/*
** Adjust DOS file position to current point.
*/
_adjust(fd) int fd; {
if(_bufuse[fd] == OUT) return (_flush(fd));
if(_bufuse[fd] == IN ) return (_backup(fd));
}
/*
** Backup DOS file position to current point.
*/
_backup(fd) int fd; {
int hi, lo;
if(lo = _bufnxt[fd] - _bufend[fd]) {
hi = -1;
if(!_seek(FROM_CUR, fd, &hi, &lo)) {
_seterr(fd);
return (EOF);
}
}
_empty(fd, YES);
return (NULL);
}
/*
** Set buffer controls to empty status.
*/
_empty(fd, mt) int fd, mt; {
_bufnxt[fd] = _bufend[fd] = _bufptr[fd];
_bufeof[fd] = NO;
if(mt) _bufuse[fd] = EMPTY;
}
/*
** Return fd's open mode, else NULL.
*/
_mode(fd) char *fd; {
if(fd < MAXFILES) return (_status[fd]);
return (NULL);
}
/*
** Set eof status for fd and
*/
_seteof(fd) int fd; {
_status[fd] |= EOFBIT;
}
/*
** Clear eof status for fd.
*/
_clreof(fd) int fd; {
_status[fd] &= ~EOFBIT;
}
/*
** Set error status for fd.
*/
_seterr(fd) int fd; {
_status[fd] |= ERRBIT;
}
/*
** Clear error status for fd.
*/
_clrerr(fd) int fd; {
_status[fd] &= ~ERRBIT;
}
/*
** Allocate n bytes of (possibly zeroed) memory.
** Entry: n = Size of the items in bytes.
** clear = "true" if clearing is desired.
** Returns the address of the allocated block of memory
** or NULL if the requested amount of space is not available.
*/
_alloc(n, clear) unsigned n, clear; {
char *oldptr;
if(n < avail(YES)) {
if(clear) pad(_memptr, NULL, n);
oldptr = _memptr;
_memptr += n;
return (oldptr);
}
return (NULL);
}
/*
** Issue extended BDOS function and return result.
** Entry: ax = function code and sub-function
** bx, cx, dx = other parameters
*/
_bdos2(ax, bx, cx, dx) int ax, bx, cx, dx; {
#asm
push bx ; preserve secondary register
mov dx,[bp+4]
mov cx,[bp+6]
mov bx,[bp+8]
mov ax,[bp+10] ; load DOS function number
int 21h ; call bdos
jnc __bdos21 ; no error
neg ax ; make error code negative
__bdos21:
pop bx ; restore secondary register
#endasm
}
/*
** Issue LSEEK call
*/
_seek(org, fd, hi, lo) int org, fd, hi, lo; {
#asm
push bx ; preserve secondary register
mov bx,[bp+4]
mov dx,[bx] ; get lo part of destination
mov bx,[bp+6]
mov cx,[bx] ; get hi part of destination
mov bx,[bp+8] ; get file descriptor
mov al,[bp+10] ; get origin code for seek
mov ah,42h ; move-file-pointer function
int 21h ; call bdos
jnc __seek1 ; error?
xor ax,ax ; yes, return false
jmp __seek2
__seek1: ; no, set hi and lo
mov bx,[bp+4] ; get address of lo
mov [bx],ax ; store low part of new position
mov bx,[bp+6] ; get address of hi
mov [bx],dx ; store high part of new position
mov ax,1 ; return true
__seek2:
pop bx ; restore secondary register
#endasm
}
/*
** Test for keyboard input
*/
_hitkey() {
#asm
mov ah,1 ; sub-service = test keyboard
int 16h ; call bdos keyboard services
jnz __hit1
xor ax,ax ; nothing there, return false
jmp __hit2
__hit1:
mov ax,1 ; character ready, return true
__hit2:
#endasm
}
/*
** Return next keyboard character
*/
_getkey() {
#asm
mov ah,0 ; sub-service = read keyboard
int 16h ; call bdos keyboard services
or al,al ; special character?
jnz __get2 ; no
mov al,ah ; yes, move it to al
cmp al,3 ; ctl-2 (simulated null)?
jne __get1 ; no
xor al,al ; yes, report zero
jmp __get2
__get1:
add al,113 ; offset to range 128-245
__get2:
xor ah,ah ; zero ah
#endasm
}
>>> CTELL.C 566
#include "stdio.h"
#include "clib.h"
extern int _bufuse[];
/*
** Return offset to current 128-byte record.
*/
ctell(fd) int fd; {
int hi, lo;
if(!_mode(fd) || !_bufuse[fd]) return (-1);
if(_adjust(fd)) return (-1);
hi = lo = 0;
_seek(FROM_CUR, fd, &hi, &lo);
return ((hi << 9) | ((lo >> 7) & 511));
}
/*
** Return offset to next byte in current 128-byte record.
*/
ctellc(fd) int fd; {
int hi, lo;
if(!_mode(fd) || !_bufuse[fd]) return (-1);
if(_adjust(fd)) return (-1);
hi = lo = 0;
_seek(FROM_CUR, fd, &hi, &lo);
return (lo & 127);
}
>>> DTOI.C 370
#include "stdio.h"
/*
** dtoi -- convert signed decimal string to integer nbr
** returns field length, else ERR on error
*/
dtoi(decstr, nbr) char *decstr; int *nbr; {
int len, s;
if((*decstr)=='-') {s=1; ++decstr;} else s=0;
if((len=utoi(decstr, nbr))<0) return ERR;
if(*nbr<0) return ERR;
if(s) {*nbr = -*nbr; return ++len;} else return len;
}
>>> EXIT.C 447
#include "stdio.h"
#include "clib.h"
/*
** Close all open files and exit to DOS.
** Entry: ec = exit code.
*/
exit(ec) int ec; {
int fd; char str[4];
ec &= 255;
if(ec) {
left(itou(ec, str, 4));
fputs("Exit Code: ", stderr);
fputs(str, stderr);
fputs("\n", stderr);
}
for(fd = 0; fd < MAXFILES; ++fd) fclose(fd);
_bdos2((RETDOS<<8)|ec, NULL, NULL, NULL);
#asm
_abort: jmp _exit
public _abort
#endasm
}
>>> FCLOSE.C 336
#include "stdio.h"
#include "clib.h"
/*
** Close fd
** Entry: fd = file descriptor for file to be closed.
** Returns NULL for success, otherwise ERR
*/
extern int _status[];
fclose(fd) int fd; {
if(!_mode(fd) || _flush(fd)) return (ERR);
if(_bdos2(CLOSE<<8, fd, NULL, NULL) == -6) return (ERR);
return (_status[fd] = NULL);
}
>>> FEOF.C 214
#include "clib.h"
extern int _status[];
/*
** Test for end-of-file status.
** Entry: fd = file descriptor
** Returns non-zero if fd is at eof, else zero.
*/
feof(fd) int fd; {
return (_status[fd] & EOFBIT);
}
>>> FERROR.C 152
#include "stdio.h"
#include "clib.h"
extern _status[];
/*
** Test for error status on fd.
*/
ferror(fd) int fd; {
return (_status[fd] & ERRBIT);
}
>>> FGETC.C 1083
#include "stdio.h"
#include "clib.h"
extern int _nextc[];
/*
** Character-stream input of one character from fd.
** Entry: fd = File descriptor of pertinent file.
** Returns the next character on success, else EOF.
*/
fgetc(fd) int fd; {
int ch; /* must be int so EOF will flow through */
if(_nextc[fd] != EOF) { /* an ungotten byte pending? */
ch = _nextc[fd];
_nextc[fd] = EOF;
return (ch & 255); /* was cooked the first time */
}
while(1) {
ch = _read(fd);
if(iscons(fd)) {
switch(ch) { /* extra console cooking */
case ABORT: exit(2);
case CR: _write(CR, stderr); _write(LF, stderr); break;
case DEL: ch = RUB;
case RUB:
case WIPE: break;
default: _write(ch, stderr);
}
}
switch(ch) { /* normal cooking */
default: return (ch);
case DOSEOF: _seteof(fd); return (EOF);
case CR: return ('\n');
case LF:
}
}
}
#asm
_getc: jmp _fgetc
public _getc
#endasm
>>> FGETS.C 1659
#include "stdio.h"
#include "clib.h"
/*
** Gets an entire string (including its newline
** terminator) or size-1 characters, whichever comes
** first. The input is terminated by a null character.
** Entry: str = Pointer to destination buffer.
** size = Size of the destination buffer.
** fd = File descriptor of pertinent file.
** Returns str on success, else NULL.
*/
fgets(str, size, fd) char *str; unsigned size, fd; {
return (_gets(str, size, fd, 1));
}
/*
** Gets an entire string from stdin (excluding its newline
** terminator) or size-1 characters, whichever comes
** first. The input is terminated by a null character.
** The user buffer must be large enough to hold the data.
** Entry: str = Pointer to destination buffer.
** Returns str on success, else NULL.
*/
gets(str) char *str; {
return (_gets(str, 32767, stdin, 0));
}
_gets(str, size, fd, nl) char *str; unsigned size, fd, nl; {
int backup; char *next;
next = str;
while(--size > 0) {
switch (*next = fgetc(fd)) {
case EOF: *next = NULL;
if(next == str) return (NULL);
return (str);
case '\n': *(next + nl) = NULL;
return (str);
case RUB: if(next > str) backup = 1; else backup = 0;
goto backout;
case WIPE: backup = next - str;
backout: if(iscons(fd)) {
++size;
while(backup--) {
fputs("\b \b", stderr);
--next; ++size;
}
continue;
}
default: ++next;
}
}
*next = NULL;
return (str);
}
>>> FOPEN.C 485
#include "stdio.h"
#include "clib.h"
/*
** Open file indicated by fn.
** Entry: fn = Null-terminated DOS file name.
** mode = "a" - append
** "r" - read
** "w" - write
** "a+" - append update
** "r+" - read update
** "w+" - write update
** Returns a file descriptor on success, else NULL.
*/
fopen(fn, mode) char *fn, *mode; {
int fd;
if(!_open(fn, mode, &fd)) return (NULL);
return (fd);
}
>>> FPRINTF.C 2133
#include "stdio.h"
/*
** fprintf(fd, ctlstring, arg, arg, ...) - Formatted print.
** Operates as described by Kernighan & Ritchie.
** b, c, d, o, s, u, and x specifications are supported.
** Note: b (binary) is a non-standard extension.
*/
fprintf(argc) int argc; {
int *nxtarg;
nxtarg = CCARGC() + &argc;
return(_print(*(--nxtarg), --nxtarg));
}
/*
** printf(ctlstring, arg, arg, ...) - Formatted print.
** Operates as described by Kernighan & Ritchie.
** b, c, d, o, s, u, and x specifications are supported.
** Note: b (binary) is a non-standard extension.
*/
printf(argc) int argc; {
return(_print(stdout, CCARGC() + &argc - 1));
}
/*
** _print(fd, ctlstring, arg, arg, ...)
** Called by fprintf() and printf().
*/
_print(fd, nxtarg) int fd, *nxtarg; {
int arg, left, pad, cc, len, maxchr, width;
char *ctl, *sptr, str[17];
cc = 0;
ctl = *nxtarg--;
while(*ctl) {
if(*ctl!='%') {fputc(*ctl++, fd); ++cc; continue;}
else ++ctl;
if(*ctl=='%') {fputc(*ctl++, fd); ++cc; continue;}
if(*ctl=='-') {left = 1; ++ctl;} else left = 0;
if(*ctl=='0') pad = '0'; else pad = ' ';
if(isdigit(*ctl)) {
width = atoi(ctl++);
while(isdigit(*ctl)) ++ctl;
}
else width = 0;
if(*ctl=='.') {
maxchr = atoi(++ctl);
while(isdigit(*ctl)) ++ctl;
}
else maxchr = 0;
arg = *nxtarg--;
sptr = str;
switch(*ctl++) {
case 'c': str[0] = arg; str[1] = NULL; break;
case 's': sptr = arg; break;
case 'd': itoa(arg,str); break;
case 'b': itoab(arg,str,2); break;
case 'o': itoab(arg,str,8); break;
case 'u': itoab(arg,str,10); break;
case 'x': itoab(arg,str,16); break;
default: return (cc);
}
len = strlen(sptr);
if(maxchr && maxchr<len) len = maxchr;
if(width>len) width = width - len; else width = 0;
if(!left) while(width--) {fputc(pad,fd); ++cc;}
while(len--) {fputc(*sptr++,fd); ++cc; }
if(left) while(width--) {fputc(pad,fd); ++cc;}
}
return(cc);
}
>>> FPUTC.C 544
#include "stdio.h"
#include "clib.h"
extern int _status[];
/*
** Character-stream output of a character to fd.
** Entry: ch = Character to write.
** fd = File descriptor of perinent file.
** Returns character written on success, else EOF.
*/
fputc(ch, fd) int ch, fd; {
switch(ch) {
case EOF: _write(DOSEOF, fd); break;
case '\n': _write(CR, fd); _write(LF, fd); break;
default: _write(ch, fd);
}
if(_status[fd] & ERRBIT) return (EOF);
return (ch);
}
#asm
_putc: jmp _fputc
public _putc
#endasm
>>> FPUTS.C 264
#include "stdio.h"
#include "clib.h"
/*
** Write a string to fd.
** Entry: string = Pointer to null-terminated string.
** fd = File descriptor of pertinent file.
*/
fputs(string, fd) char *string; int fd; {
while(*string) fputc(*string++, fd) ;
}
>>> FREAD.C 887
#include "clib.h"
extern int _status[];
/*
** Item-stream read from fd.
** Entry: buf = address of target buffer
** sz = size of items in bytes
** n = number of items to read
** fd = file descriptor
** Returns a count of the items actually read.
** Use feof() and ferror() to determine file status.
*/
fread(buf, sz, n, fd) unsigned char *buf; unsigned sz, n, fd; {
return (read(fd, buf, n*sz)/sz);
}
/*
** Binary-stream read from fd.
** Entry: fd = file descriptor
** buf = address of target buffer
** n = number of bytes to read
** Returns a count of the bytes actually read.
** Use feof() and ferror() to determine file status.
*/
read(fd, buf, n) unsigned fd, n; unsigned char *buf; {
unsigned cnt;
cnt = 0;
while(n--) {
*buf++ = _read(fd);
if(_status[fd] & (ERRBIT | EOFBIT)) break;
++cnt;
}
return (cnt);
}
>>> FREE.C 374
extern char *_memptr;
/*
** free(ptr) - Free previously allocated memory block.
** Memory must be freed in the reverse order from which
** it was allocated.
** ptr = Value returned by calloc() or malloc().
** Returns ptr if successful or NULL otherwise.
*/
free(ptr) char *ptr; {
return (_memptr = ptr);
}
#asm
_cfree: jmp _free
public _cfree
#endasm
>>> FREOPEN.C 799
#include <stdio.h>
#include "clib.h"
/*
** Close previously opened fd and reopen it.
** Entry: fn = Null-terminated DOS file name.
** mode = "a" - append
** "r" - read
** "w" - write
** "a+" - append update
** "r+" - read update
** "w+" - write update
** fd = File descriptor of pertinent file.
** Returns the original fd on success, else NULL.
*/
extern int _status[];
freopen(fn, mode, fd) char *fn, *mode; int fd; {
int tfd;
if(fclose(fd)) return (NULL);
if(!_open(fn, mode, &tfd)) return (NULL);
if(fd != tfd) {
if(_bdos2(FORCE<<8, tfd, fd, NULL) < 0) return (NULL);
_status[fd] = _status[tfd];
_status[tfd] = 0; /* leaves DOS using two handles */
}
return (fd);
}
>>> FSCANF.C 2479
#include "stdio.h"
/*
** fscanf(fd, ctlstring, arg, arg, ...) - Formatted read.
** Operates as described by Kernighan & Ritchie.
** b, c, d, o, s, u, and x specifications are supported.
** Note: b (binary) is a non-standard extension.
*/
fscanf(argc) int argc; {
int *nxtarg;
nxtarg = CCARGC() + &argc;
return (_scan(*(--nxtarg), --nxtarg));
}
/*
** scanf(ctlstring, arg, arg, ...) - Formatted read.
** Operates as described by Kernighan & Ritchie.
** b, c, d, o, s, u, and x specifications are supported.
** Note: b (binary) is a non-standard extension.
*/
scanf(argc) int argc; {
return (_scan(stdin, CCARGC() + &argc - 1));
}
/*
** _scan(fd, ctlstring, arg, arg, ...) - Formatted read.
** Called by fscanf() and scanf().
*/
_scan(fd,nxtarg) int fd, *nxtarg; {
char *carg, *ctl;
unsigned u;
int *narg, wast, ac, width, ch, cnv, base, ovfl, sign;
ac = 0;
ctl = *nxtarg--;
while(*ctl) {
if(isspace(*ctl)) {++ctl; continue;}
if(*ctl++ != '%') continue;
if(*ctl == '*') {narg = carg = &wast; ++ctl;}
else narg = carg = *nxtarg--;
ctl += utoi(ctl, &width);
if(!width) width = 32767;
if(!(cnv = *ctl++)) break;
while(isspace(ch = fgetc(fd))) ;
if(ch == EOF) {if(ac) break; else return(EOF);}
ungetc(ch,fd);
switch(cnv) {
case 'c':
*carg = fgetc(fd);
break;
case 's':
while(width--) {
if((*carg = fgetc(fd)) == EOF) break;
if(isspace(*carg)) break;
if(carg != &wast) ++carg;
}
*carg = 0;
break;
default:
switch(cnv) {
case 'b': base = 2; sign = 1; ovfl = 32767; break;
case 'd': base = 10; sign = 0; ovfl = 3276; break;
case 'o': base = 8; sign = 1; ovfl = 8191; break;
case 'u': base = 10; sign = 1; ovfl = 6553; break;
case 'x': base = 16; sign = 1; ovfl = 4095; break;
default: return (ac);
}
*narg = u = 0;
while(width-- && !isspace(ch=fgetc(fd)) && ch!=EOF) {
if(!sign)
if(ch == '-') {sign = -1; continue;}
else sign = 1;
if(ch < '0') return (ac);
if(ch >= 'a') ch -= 87;
else if(ch >= 'A') ch -= 55;
else ch -= '0';
if(ch >= base || u > ovfl) return (ac);
u = u * base + ch;
}
*narg = sign * u;
}
++ac;
}
return (ac);
}
>>> FWRITE.C 959
#include "clib.h"
extern int _status[];
/*
** Item-stream write to fd.
** Entry: buf = address of source buffer
** sz = size of items in bytes
** n = number of items to write
** fd = file descriptor
** Returns a count of the items actually written or
** zero if an error occurred.
** May use ferror(), as always, to detect errors.
*/
fwrite(buf, sz, n, fd) unsigned char *buf; unsigned sz, n, fd; {
if(write(fd, buf, n*sz) == -1) return (0);
return (n);
}
/*
** Binary-stream write to fd.
** Entry: fd = file descriptor
** buf = address of source buffer
** n = number of bytes to write
** Returns a count of the bytes actually written or
** -1 if an error occurred.
** May use ferror(), as always, to detect errors.
*/
write(fd, buf, n) unsigned fd, n; unsigned char *buf; {
unsigned cnt;
cnt = n;
while(cnt--) {
_write(*buf++, fd);
if(_status[fd] & ERRBIT) return (-1);
}
return (n);
}
>>> GETARG.C 626
#include "stdio.h"
/*
** Get command line argument.
** Entry: n = Number of the argument.
** s = Destination string pointer.
** size = Size of destination string.
** argc = Argument count from main().
** argv = Argument vector(s) from main().
** Returns number of characters moved on success,
** else EOF.
*/
getarg(n, s, size, argc, argv)
int n; char *s; int size, argc, argv[]; {
char *str;
int i;
if(n < 0 | n >= argc) {
*s = NULL;
return EOF;
}
i = 0;
str=argv[n];
while(i<size) {
if((s[i]=str[i])==NULL) break;
++i;
}
s[i]=NULL;
return i;
}
>>> GETCHAR.C 111
#include "stdio.h"
/*
** Get next character from standard input.
*/
getchar() {
return (fgetc(stdin));
}
>>> IS.C 2057
/*
** All character classification functions except isascii().
** Integer argument (c) must be in ASCII range (0-127) for
** dependable answers.
*/
#define ALNUM 1
#define ALPHA 2
#define CNTRL 4
#define DIGIT 8
#define GRAPH 16
#define LOWER 32
#define PRINT 64
#define PUNCT 128
#define BLANK 256
#define UPPER 512
#define XDIGIT 1024
int _is[128] = {
0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
0x004, 0x104, 0x104, 0x104, 0x104, 0x104, 0x004, 0x004,
0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
0x140, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459,
0x459, 0x459, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
0x0D0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253,
0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
0x253, 0x253, 0x253, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
0x0D0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073,
0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
0x073, 0x073, 0x073, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x004
};
isalnum (c) int c; {return (_is[c] & ALNUM );} /* 'a'-'z', 'A'-'Z', '0'-'9' */
isalpha (c) int c; {return (_is[c] & ALPHA );} /* 'a'-'z', 'A'-'Z' */
iscntrl (c) int c; {return (_is[c] & CNTRL );} /* 0-31, 127 */
isdigit (c) int c; {return (_is[c] & DIGIT );} /* '0'-'9' */
isgraph (c) int c; {return (_is[c] & GRAPH );} /* '!'-'~' */
islower (c) int c; {return (_is[c] & LOWER );} /* 'a'-'z' */
isprint (c) int c; {return (_is[c] & PRINT );} /* ' '-'~' */
ispunct (c) int c; {return (_is[c] & PUNCT );} /* !alnum && !cntrl && !space */
isspace (c) int c; {return (_is[c] & BLANK );} /* HT, LF, VT, FF, CR, ' ' */
isupper (c) int c; {return (_is[c] & UPPER );} /* 'A'-'Z' */
isxdigit(c) int c; {return (_is[c] & XDIGIT);} /* '0'-'9', 'a'-'f', 'A'-'F' */
>>> ISASCII.C 108
/*
** return 'true' if c is an ASCII character (0-127)
*/
isascii(c) unsigned c; {
return (c < 128);
}
>>> ISATTY.C 374
/*
** Return "true" if fd is a device, else "false"
*/
isatty(fd) int fd; {
fd; /* fetch handle */
#asm
push bx ; save 2nd reg
mov bx,ax ; place handle
mov ax,4400h ; ioctl get info function
int 21h ; call BDOS
pop bx ; restore 2nd reg
mov ax,dx ; fetch info bits
and ax,80h ; isdev bit
#endasm
}
>>> ISCONS.C 769
/*
** Determine if fd is the console.
*/
#include <stdio.h>
extern int _cons[];
iscons(fd) int fd; {
if(_cons[fd] == NULL) {
if(_iscons(fd)) _cons[fd] = 2;
else _cons[fd] = 1;
}
if(_cons[fd] == 1) return (NO);
return (YES);
}
/*
** Call DOS only the first time for a file.
*/
_iscons(fd) int fd; {
fd; /* fetch handle */
#asm
push bx ; save 2nd reg
mov bx,ax ; place handle
mov ax,4400h ; ioctl get info function
int 21h ; call BDOS
pop bx ; restore 2nd reg
mov ax,dx ; fetch info bits
and ax,83h ; keep device and console bits
cmp ax,80h ; device and console?
jg __cons1
xor ax,ax ; return false if not device and console
__cons1:
#endasm
}
>>> ITOA.C 276
/*
** itoa(n,s) - Convert n to characters in s
*/
itoa(n, s) char *s; int n; {
int sign;
char *ptr;
ptr = s;
if ((sign = n) < 0) n = -n;
do {
*ptr++ = n % 10 + '0';
} while ((n = n / 10) > 0);
if (sign < 0) *ptr++ = '-';
*ptr = '\0';
reverse(s);
}
>>> ITOAB.C 425
/*
** itoab(n,s,b) - Convert "unsigned" n to characters in s using base b.
** NOTE: This is a non-standard function.
*/
itoab(n, s, b) int n; char *s; int b; {
char *ptr;
int lowbit;
ptr = s;
b >>= 1;
do {
lowbit = n & 1;
n = (n >> 1) & 32767;
*ptr = ((n % b) << 1) + lowbit;
if(*ptr < 10) *ptr += '0'; else *ptr += 55;
++ptr;
} while(n /= b);
*ptr = 0;
reverse (s);
}
>>> ITOD.C 623
#include "stdio.h"
/*
** itod -- convert nbr to signed decimal string of width sz
** right adjusted, blank filled; returns str
**
** if sz > 0 terminate with null byte
** if sz = 0 find end of string
** if sz < 0 use last byte for data
*/
itod(nbr, str, sz) int nbr; char str[]; int sz; {
char sgn;
if(nbr<0) {nbr = -nbr; sgn='-';}
else sgn=' ';
if(sz>0) str[--sz]=NULL;
else if(sz<0) sz = -sz;
else while(str[sz]!=NULL) ++sz;
while(sz) {
str[--sz]=(nbr%10+'0');
if((nbr=nbr/10)==0) break;
}
if(sz) str[--sz]=sgn;
while(sz>0) str[--sz]=' ';
return str;
}
>>> ITOO.C 541
/*
** itoo -- converts nbr to octal string of length sz
** right adjusted and blank filled, returns str
**
** if sz > 0 terminate with null byte
** if sz = 0 find end of string
** if sz < 0 use last byte for data
*/
itoo(nbr, str, sz) int nbr; char str[]; int sz; {
int digit;
if(sz>0) str[--sz]=0;
else if(sz<0) sz = -sz;
else while(str[sz]!=0) ++sz;
while(sz) {
digit=nbr&7; nbr=(nbr>>3)&8191;
str[--sz]=digit+48;
if(nbr==0) break;
}
while(sz) str[--sz]=' ';
return str;
}
>>> ITOU.C 621
#include "stdio.h"
/*
** itou -- convert nbr to unsigned decimal string of width sz
** right adjusted, blank filled; returns str
**
** if sz > 0 terminate with null byte
** if sz = 0 find end of string
** if sz < 0 use last byte for data
*/
itou(nbr, str, sz) int nbr; char str[]; int sz; {
int lowbit;
if(sz>0) str[--sz]=NULL;
else if(sz<0) sz = -sz;
else while(str[sz]!=NULL) ++sz;
while(sz) {
lowbit=nbr&1;
nbr=(nbr>>1)&32767; /* divide by 2 */
str[--sz]=((nbr%5)<<1)+lowbit+'0';
if((nbr=nbr/5)==0) break;
}
while(sz) str[--sz]=' ';
return str;
}
>>> ITOX.C 596
/*
** itox -- converts nbr to hex string of length sz
** right adjusted and blank filled, returns str
**
** if sz > 0 terminate with null byte
** if sz = 0 find end of string
** if sz < 0 use last byte for data
*/
itox(nbr, str, sz) int nbr; char str[]; int sz; {
int digit, offset;
if(sz>0) str[--sz]=0;
else if(sz<0) sz = -sz;
else while(str[sz]!=0) ++sz;
while(sz) {
digit=nbr&15; nbr=(nbr>>4)&4095;
if(digit<10) offset=48; else offset=55;
str[--sz]=digit+offset;
if(nbr==0) break;
}
while(sz) str[--sz]=' ';
return str;
}
>>> LEFT.C 166
/*
** left -- left adjust and null terminate a string
*/
left(str) char *str; {
char *str2;
str2=str;
while(*str2==' ') ++str2;
while(*str++ = *str2++);
}
>>> LEXCMP.C 1380
char _lex[128] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* NUL - / */
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, /* 0-9 */
48, 49, 50, 51, 52, 53, 54, /* : ; < = > ? @ */
75, 76, 77, 78, 79, 80, 81, 82, 83, 84, /* A-Z */
85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
95, 96, 97, 98, 99,100,
55, 56, 57, 58, 59, 60, /* [ \ ] ^ _ ` */
75, 76, 77, 78, 79, 80, 81, 82, 83, 84, /* a-z */
85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
95, 96, 97, 98, 99,100,
61, 62, 63, 64, /* { | } ~ */
127}; /* DEL */
/*
** lexcmp(s, t) - Return a number <0, 0, or >0
** as s is <, =, or > t.
*/
lexcmp(s, t) char *s, *t; {
while(lexorder(*s, *t) == 0)
if(*s++) ++t;
else return (0);
return (lexorder(*s, *t));
}
/*
** lexorder(c1, c2)
**
** Return a negative, zero, or positive number if
** c1 is less than, equal to, or greater than c2,
** based on a lexicographical (dictionary order)
** colating sequence.
**
*/
lexorder(c1, c2) int c1, c2; {
return(_lex[c1] - _lex[c2]);
}
>>> MALLOC.C 237
#include "stdio.h"
/*
** Memory allocation of size bytes.
** size = Size of the block in bytes.
** Returns the address of the allocated block,
** else NULL for failure.
*/
malloc(size) unsigned size; {
return (_alloc(size, NO));
}
>>> OTOI.C 368
#include "stdio.h"
/*
** otoi -- convert unsigned octal string to integer nbr
** returns field size, else ERR on error
*/
otoi(octstr, nbr) char *octstr; int *nbr; {
int d,t; d=0;
*nbr=0;
while((*octstr>='0')&(*octstr<='7')) {
t=*nbr;
t=(t<<3) + (*octstr++ - '0');
if ((t>=0)&(*nbr<0)) return ERR;
d++; *nbr=t;
}
return d;
}
>>> PAD.C 123
/*
** Place n occurrences of ch at dest.
*/
pad(dest, ch, n) char *dest; unsigned n, ch; {
while(n--) *dest++ = ch;
}
>>> POLL.C 390
#include "stdio.h"
#include "clib.h"
/*
** Poll for console input or interruption
*/
poll(pause) int pause; {
int i;
if(i = _hitkey()) i = _getkey();
if(pause) {
if(i == PAUSE) {
i = _getkey(); /* wait for next character */
if(i == ABORT) exit(2); /* indicate abnormal exit */
return (0);
}
if(i == ABORT) exit(2);
}
return (i);
}
>>> PUTCHAR.C 122
#include "stdio.h"
/*
** Write character to standard output.
*/
putchar(ch) int ch; {
return (fputc(ch, stdout));
}
>>> PUTS.C 144
#include "stdio.h"
/*
** Write string to standard output.
*/
puts(string) char *string; {
fputs(string, stdout);
fputc('\n', stdout);
}
>>> RENAME.C 711
#include "stdio.h"
#include "clib.h"
/*
** Rename a file.
** from = address of old filename.
** to = address of new filename.
** Returns NULL on success, else ERR.
*/
rename(from, to) char *from, *to; {
if(_rename(from, to)) return (NULL);
return (ERR);
}
_rename(old, new) char *old, *new; {
#asm
push ds ; ds:dx points to old name
pop es ; es:di points to new name
mov di,[bp+4] ; get "new" offset
mov dx,[bp+6] ; get "old" offset
mov ah,56h ; rename function
int 21h ; call bdos
jnc __ren1 ; error?
xor ax,ax ; yes, return false
jmp __ren2
__ren1: ; no, set hi and lo
mov ax,1 ; return true
__ren2:
#endasm
}
>>> REVERSE.C 170
/*
** reverse string in place
*/
reverse(s) char *s; {
char *j;
int c;
j = s + strlen(s) - 1;
while(s < j) {
c = *s;
*s++ = *j;
*j-- = c;
}
}
>>> REWIND.C 89
/*
** Rewind file to beginning.
*/
rewind(fd) int fd; {
return(cseek(fd, 0, 0));
}
>>> SIGN.C 154
/*
** sign -- return -1, 0, +1 depending on the sign of nbr
*/
sign(nbr) int nbr; {
if(nbr > 0) return 1;
if(nbr == 0) return 0;
return -1;
}
>>> STRCAT.C 177
/*
** concatenate t to end of s
** s must be large enough
*/
strcat(s, t) char *s, *t; {
char *d;
d = s;
--s;
while (*++s) ;
while (*s++ = *t++) ;
return (d);
}
>>> STRCHR.C 177
/*
** return pointer to 1st occurrence of c in str, else 0
*/
strchr(str, c) char *str, c; {
while(*str) {
if(*str == c) return (str);
++str;
}
return (0);
}
>>> STRCMP.C 185
/*
** return <0, 0, >0 a_ording to
** s<t, s=t, s>t
*/
strcmp(s, t) char *s, *t; {
while(*s == *t) {
if(*s == 0) return (0);
++s; ++t;
}
return (*s - *t);
}
>>> STRCPY.C 113
/*
** copy t to s
*/
strcpy(s, t) char *s, *t; {
char *d;
d = s;
while (*s++ = *t++) ;
return (d);
}
>>> STRLEN.C 357
/*
** return length of string s (fast version)
*/
strlen(s) char *s; {
#asm
xor al,al ; set search value to zero
mov cx,65535 ; set huge maximum
mov di,[bp+4] ; get address of s
cld ; set direction flag forward
repne scasb ; scan for zero
mov ax,65534
sub ax,cx ; calc and return length
#endasm
}
>>> STRNCAT.C 255
/*
** concatenate n bytes max from t to end of s
** s must be large enough
*/
strncat(s, t, n) char *s, *t; int n; {
char *d;
d = s;
--s;
while(*++s) ;
while(n--) {
if(*s++ = *t++) continue;
return(d);
}
*s = 0;
return(d);
}
>>> STRNCMP.C 333
/*
** strncmp(s,t,n) - Compares two strings for at most n
** characters and returns an integer
** >0, =0, or <0 as s is >t, =t, or <t.
*/
strncmp(s, t, n) char *s, *t; int n; {
while(n && *s==*t) {
if (*s == 0) return (0);
++s; ++t; --n;
}
if(n) return (*s - *t);
return (0);
}
>>> STRNCPY.C 253
/*
** copy n characters from sour to dest (null padding)
*/
strncpy(dest, sour, n) char *dest, *sour; int n; {
char *d;
d = dest;
while(n-- > 0) {
if(*d++ = *sour++) continue;
while(n-- > 0) *d++ = 0;
}
*d = 0;
return (dest);
}
>>> STRRCHR.C 315
/*
** strrchr(s,c) - Search s for rightmost occurrance of c.
** s = Pointer to string to be searched.
** c = Character to search for.
** Returns pointer to rightmost c or NULL.
*/
strrchr(s, c) char *s, c; {
char *ptr;
ptr = 0;
while(*s) {
if(*s==c) ptr = s;
++s;
}
return (ptr);
}
>>> TOASCII.C 77
/*
** return ASCII equivalent of c
*/
toascii(c) int c; {
return (c);
}
>>> TOLOWER.C 131
/*
** return lower-case of c if upper-case, else c
*/
tolower(c) int c; {
if(c<='Z' && c>='A') return (c+32);
return (c);
}
>>> TOUPPER.C 137
/*
** return upper-case of c if it is lower-case, else c
*/
toupper(c) int c; {
if(c<='z' && c>='a') return (c-32);
return (c);
}
>>> UNGETC.C 295
#include "stdio.h"
extern _nextc[];
/*
** Put c back into file fd.
** Entry: c = character to put back
** fd = file descriptor
** Returns c if successful, else EOF.
*/
ungetc(c, fd) int c, fd; {
if(!_mode(fd) || _nextc[fd]!=EOF || c==EOF) return (EOF);
return (_nextc[fd] = c);
}
>>> UNLINK.C 473
#include "stdio.h"
#include "clib.h"
/*
** Unlink (delete) the named file.
** Entry: fn = Null-terminated DOS file path\name.
** Returns NULL on success, else ERR.
*/
unlink(fn) char *fn; {
fn; /* load fn into ax */
#asm
mov dx,ax ; put fn in its place
mov ah,41h ; delete function code
int 21h
mov ax,0
jnc __unlk ; return NULL
mov ax,-2 ; return ERR
__unlk:
#endasm
}
#asm
_delete: jmp _unlink
public _delete
#endasm
>>> UTOI.C 365
#include "stdio.h"
/*
** utoi -- convert unsigned decimal string to integer nbr
** returns field size, else ERR on error
*/
utoi(decstr, nbr) char *decstr; int *nbr; {
int d,t; d=0;
*nbr=0;
while((*decstr>='0')&(*decstr<='9')) {
t=*nbr;t=(10*t) + (*decstr++ - '0');
if ((t>=0)&(*nbr<0)) return ERR;
d++; *nbr=t;
}
return d;
}
>>> XTOI.C 729
#include stdio.h
/*
** xtoi -- convert hex string to integer nbr
** returns field size, else ERR on error
*/
xtoi(hexstr, nbr) char *hexstr; int *nbr; {
int d, b; char *cp;
d = *nbr = 0; cp = hexstr;
while(*cp == '0') ++cp;
while(1) {
switch(*cp) {
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8':
case '9': b=48; break;
case 'A': case 'B': case 'C':
case 'D': case 'E': case 'F': b=55; break;
case 'a': case 'b': case 'c':
case 'd': case 'e': case 'f': b=87; break;
default: return (cp - hexstr);
}
if(d < 4) ++d; else return (ERR);
*nbr = (*nbr << 4) + (*cp++ - b);
}
}